/*
 * libArchivoLog.c
 *
 *  Created on: 14/04/2012
 *      Author: utnso
 */

#include "libArchivoLog.h"

//VARIABLES GLOBALES PURAMENTE A ESTE ARCHIVO
static int32_t fp = -1;
static char* pathArchLog;
static uint8_t nivelLogActual = NIVEL_LOG_OBLIGATORIO;
static pthread_mutex_t mutexArchLogs = PTHREAD_MUTEX_INITIALIZER;

void inicializarPathLogueo(char* path){
	pathArchLog = (char*) malloc(strlen(path) + 1);
	strcpy(pathArchLog, path);
}

void inicializarNivelLogueo(uint8_t nivelLog){
	if(nivelLog >= NIVEL_LOG_NULO && nivelLog <= NIVEL_LOG_ALTO_IMPR){
		nivelLogActual = nivelLog;
	}else if(nivelLog < NIVEL_LOG_NULO){
		nivelLogActual = NIVEL_LOG_NULO;
	}else{
		nivelLogActual = NIVEL_LOG_ALTO_IMPR;
	}
}

void loguearCadena(char* cadena, uint8_t nivelLog){
	//LA CADENA DEBE TERMINAR EN \n Y NO DEBE CONTENER \0
	if(nivelLogActual > 0 && nivelLogActual >= nivelLog){
		pthread_mutex_lock(&mutexArchLogs);
		//ESTA SETEADO EL NIVEL DE LOG NECESARIO PARA LOGUEAR ESTE EVENTO
		if(div(nivelLogActual, 2).rem == 0){
			//EL NIVEL DE LOG ES PAR, ADEMAS DE LOGUEAR EL EVENTO EN UN ARCHIVO SE IMPRIME POR CONSOLA
			printf("%s", cadena);
		}
		if(fp == -1){
			//NO SE CUENTA CON INFORMACION DEL ARCHIVO
			fp = open(pathArchLog, O_WRONLY | O_CREAT, 0600);
		}

		write(fp, cadena, strlen(cadena));
		pthread_mutex_unlock(&mutexArchLogs);
	}
}

void loguearDatos(char* tipo, time_t tiempo, char* nombreProceso, int32_t idProceso, int32_t idThread, char* comentario, uint8_t nivelLog){
	if(nivelLogActual > 0 && nivelLogActual >= nivelLog){
		//SE PASARA AL FORMATO [tipo] horas:minutos:segundos:milisegundos nombreProceso/(idProceso:idThread): comentario\n
		char* buffer = (char*) malloc(200);
		memset(buffer, '\0', 200);

		//CASTEO EL TIEMPO A CHAR
		struct tm* tiempoLocal;
		tiempoLocal = localtime(&tiempo);
		strftime(buffer, 80, "%H:%M:%S:000", tiempoLocal);
		char* bufferTiempo = (char*) malloc(strlen(buffer) + 1);
		memset(bufferTiempo, '\0', strlen(buffer) + 1);
		strcpy(bufferTiempo, buffer);

		//CASTEO EL ID DEL PROCESO A CHAR
		char* bufferIdProceso;
		intAChar(&bufferIdProceso, idProceso, 10);

		//CASTEO EL ID DEL THREAD A CHAR
		char* bufferIdThread;
		intAChar(&bufferIdThread, idThread, 10);

		char* cadena = malloc(1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1 + 1 + strlen(comentario) + 1 + 1);
		memset(cadena, '\0', 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1 + 1 + strlen(comentario) + 1 + 1);
		strcpy(cadena, "[");
		strcpy(cadena + 1, tipo);
		strcpy(cadena + 1 + strlen(tipo), "]");
		strcpy(cadena + 1 + strlen(tipo) + 1, " ");
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1, bufferTiempo);
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo), " ");
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1, nombreProceso);
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso), "/");
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1, "(");
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1, bufferIdProceso);
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso), ":");
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1, bufferIdThread);
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread), ")");
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1, " ");
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1, comentario);
		strcpy(cadena + 1 + strlen(tipo) + 1 + 1 + strlen(bufferTiempo) + 1 + strlen(nombreProceso) + 1 + 1 + strlen(bufferIdProceso) + 1 + strlen(bufferIdThread) + 1 + 1 + strlen(comentario), "\n");

		free(buffer);
		free(bufferTiempo);
		free(bufferIdProceso);
		free(bufferIdThread);

		loguearCadena(cadena, nivelLog);

		free(cadena);
	}
}

void loguearTemplate(uint8_t nivelLog, char* template, ...){
	if(nivelLogActual > 0 && nivelLogActual >= nivelLog){
		va_list arg;
		va_start(arg, template);
		char* logAux = (char*) malloc(MAX_LINEA_LOG);
		vsprintf(logAux, template, arg);
		char* log = (char*) malloc(strlen(logAux) + 1);
		strcpy(log, logAux);
		free(logAux);
		loguearCadena(log, nivelLog);
		free(log);
	}
}

void cerrarArchivoLog(void){
	pthread_mutex_lock(&mutexArchLogs);
	close(fp);
	fp = -1;
	pthread_mutex_unlock(&mutexArchLogs);
}
